package mutsumimod.patches;

import com.evacipated.cardcrawl.modthespire.lib.*;
import com.evacipated.cardcrawl.modthespire.patcher.PatchingException;
import com.megacrit.cardcrawl.actions.common.GainBlockAction;
import com.megacrit.cardcrawl.cards.AbstractCard;
import com.megacrit.cardcrawl.cards.DamageInfo;
import com.megacrit.cardcrawl.characters.AbstractPlayer;
import com.megacrit.cardcrawl.core.AbstractCreature;
import com.megacrit.cardcrawl.dungeons.AbstractDungeon;
import com.megacrit.cardcrawl.monsters.AbstractMonster;
import javassist.CannotCompileException;
import javassist.CtBehavior;
import mutsumimod.powers.BreakPower;
import mutsumimod.powers.CrossingSeaPower;

import java.util.ArrayList;

public class CrossingSeaPatch extends BasePatch {
    @SpirePatch(
            clz = AbstractMonster.class,
            method = "damage",
            paramtypez = {
                    DamageInfo.class
            }
    )
    public static class MonsterDamagePatch {
        @SpireInsertPatch(
                locator = Locator.class,
                localvars = {"damageAmount"}
        )
        public static SpireReturn insert(AbstractMonster __instance,DamageInfo info,@ByRef int[] damageAmount){
            if(AbstractDungeon.player.hasPower(CrossingSeaPower.POWER_ID)){
                if(!__instance.isDying&&!__instance.isEscaping&&damageAmount[0]>0){
                    applyPowerMonster(new BreakPower(__instance,damageAmount[0]),damageAmount[0],__instance);
                    return SpireReturn.Return();
                }
            }
            return SpireReturn.Continue();
        }

        private static class Locator extends SpireInsertLocator {
            public int[] Locate(CtBehavior ctMethodToPatch) throws CannotCompileException, PatchingException {
                Matcher finalMatcher = new Matcher.FieldAccessMatcher(AbstractMonster.class, "isDying");

                int[] lines = LineFinder.findInOrder(ctMethodToPatch, new ArrayList<Matcher>(), finalMatcher);
                return new int[]{lines[0]};
            }
        }
    }

    @SpirePatch(
            clz = AbstractPlayer.class,
            method = "damage",
            paramtypez = {
                    DamageInfo.class
            }
    )
    public static class PlayerDamagePatch {
        @SpireInsertPatch(
                locator = Locator.class,
                localvars = {"damageAmount"}
        )
        public static SpireReturn insert(AbstractPlayer __instance,DamageInfo info,@ByRef int[] damageAmount){
            if(AbstractDungeon.player.hasPower(CrossingSeaPower.POWER_ID)){
                if(damageAmount[0]>0){
                    applyPowerSelf(new BreakPower(__instance,damageAmount[0]),damageAmount[0]);
                    return SpireReturn.Return();
                }
            }
            return SpireReturn.Continue();
        }

        private static class Locator extends SpireInsertLocator {
            public int[] Locate(CtBehavior ctMethodToPatch) throws CannotCompileException, PatchingException {
                Matcher finalMatcher = new Matcher.MethodCallMatcher(AbstractPlayer.class, "decrementBlock");

                int[] lines = LineFinder.findInOrder(ctMethodToPatch, new ArrayList<Matcher>(), finalMatcher);
                return new int[]{lines[0]};
            }
        }
    }
}
